﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Controls;

using GalaSoft.MvvmLight.Command;

using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Enum;

using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Manager.Application.ViewModel.BaseClass;

namespace Rio.Manager.Application.ViewModel.Administration
{
    public class GeneralParametersTabViewModel : TabViewModelBase
    {
        #region Fields

        private ObservableCollection<GeneralParameter> _parameters;
        private GeneralParameter _selectedParameter;

        #endregion Fields

        #region Constructors

        public GeneralParametersTabViewModel()
            : base()
        {
            CanCloseTab = true;
        }

        #endregion Constructors

        #region Properties

        public RelayCommand InitializationCommand
        {
            get;
            set;
        }

        public ObservableCollection<GeneralParameter> Parameters
        {
            get { return _parameters; }
            set
            {
                _parameters = value;
                RaisePropertyChanged("Parameters");
            }
        }

        public RelayCommand SaveParameterCommand
        {
            get;
            set;
        }

        public GeneralParameter SelectedParameter
        {
            get { return _selectedParameter; }
            set
            {
                if (value != this._selectedParameter)
                {
                    _selectedParameter = value;
                    RaisePropertyChanged("SelectedParameter");

                    ValidateMandatoryValue();
                    ValidateTypeOfValue();
                }
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Inits the commands.
        /// </summary>
        public override void InitCommands()
        {
            SaveParameterCommand = new RelayCommand(
                SaveParameter,
                () => !HasErrors);

            InitializationCommand = new RelayCommand(Initialization);
        }

        /// <summary>
        /// Inits the labels.
        /// </summary>
        public override void InitLabels()
        {
            TabTitle = Resx.GetLabel(ResxRioManager.LIST_ALL_GENERAL_PARAMETERS);
        }

        /// <summary>
        /// Types the initialization.
        /// </summary>
        private void Initialization()
        {
            InitLabels();

            BusyIndicator.Clear();
            BusyIndicator.AddBusyTask();

            BusinessEntitiesDomainContext businessEntitiesDomainContext = new BusinessEntitiesDomainContext();
            businessEntitiesDomainContext.GetAllGeneralParameters(
                delegate(InvokeOperation<IEnumerable<GeneralParameter>> retr)
                {
                    BusyIndicator.RemoveBusyTask();

                    if (retr.Error == null && retr.Value != null)
                    {
                        Parameters = new ObservableCollection<GeneralParameter>(retr.Value);
                    }
                },
                null);
        }

        /// <summary>
        /// Saves the parameter.
        /// </summary>
        private void SaveParameter()
        {
            BusyIndicator.Clear();
            BusyIndicator.AddBusyTask();

            BusinessEntitiesDomainContext businessEntitiesDomainContext = new BusinessEntitiesDomainContext();
            businessEntitiesDomainContext.UpdateGeneralParameter(SelectedParameter);

            BusyIndicator.RemoveBusyTask();
        }

        /// <summary>
        /// Validates the mandatory value.
        /// </summary>
        private void ValidateMandatoryValue()
        {
            string error = "Value is mandatory.";

            if (SelectedParameter.IsMandatory && String.IsNullOrWhiteSpace(SelectedParameter.Value))
            {
                this.AddError("SelectedParameter.Value", error);
            }
            else
            {
                this.RemoveError("SelectedParameter.Value", error);
            }
        }

        /// <summary>
        /// Validates the type of value.
        /// </summary>
        private void ValidateTypeOfValue()
        {
            string error;

            switch (SelectedParameter.ValueType)
            {
                case GeneralParameterType.Integer:
                    error = "Value must be an integer.";

                    long longParseResult = -1;
                    if (Int64.TryParse(SelectedParameter.Value, out longParseResult))
                    {
                        this.RemoveError("SelectedParameter.Value", error);
                    }
                    else
                    {
                        this.AddError("SelectedParameter.Value", error);
                    }
                    break;
                case GeneralParameterType.Decimal:
                    error = "Value must be a decimal.";

                    double doubleParseResult = -1;
                    if (Double.TryParse(SelectedParameter.Value, out doubleParseResult))
                    {
                        this.RemoveError("SelectedParameter.Value", error);
                    }
                    else
                    {
                        this.AddError("SelectedParameter.Value", error);
                    }
                    break;
                case GeneralParameterType.Boolean:
                    error = "Value must be a boolean.";

                    bool boolParseResult;
                    if (Boolean.TryParse(SelectedParameter.Value, out boolParseResult))
                    {
                        this.RemoveError("SelectedParameter.Value", error);
                    }
                    else
                    {
                        this.AddError("SelectedParameter.Value", error);
                    }
                    break;
            }
        }

        #endregion Methods
    }
}